package com.oepm.web.controller;

import com.oepm.biz.AcademyBiz;
import com.oepm.biz.UserBiz;
import com.oepm.common.entity.Result;
import com.oepm.common.entity.Meta;
import com.oepm.common.utils.JWTUtil;
import com.oepm.dao.entity.*;

import com.oepm.common.utils.RoleUtil;
import com.oepm.vo.DataVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@CrossOrigin//解决跨域
@RestController
@Api(tags = "学生表API")
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserBiz userBiz;
    @Autowired
    private AcademyBiz acadenyBiz;

    @Value(value = "${upload_path}")
    private String upload_path;//资源文件绝对地址目录

    @GetMapping("/selectId/{userid}")
    @ApiOperation("查询用户")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3"})
    public Result selectUserByuserId(HttpServletRequest request,@PathVariable String userid){
        Result result;
        String token=request.getHeader("Authorization");
        String academy = JWTUtil.getAcademy(token);
        UserVo userVo = new UserVo();
        userVo.setUserid(userid);
        userVo.setAcademy(academy);
        UserVo userVo1 = userBiz.searchUser(userVo);
        if(userVo1 ==null){
            result = new Result(Meta.NOTFOUND);
            return result;
        }else{
            ArrayList<UserVo> list = new ArrayList<>();
            list.add(userVo1);
            result = new Result(Meta.SUCCESS);
            result.setData(list);
            return result;
        }

    }

    @GetMapping("/select")
    @ApiOperation("查询全部用户")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3"})
    public Result selectAll(HttpServletRequest request,QueryInfo queryInfo){
        String token=request.getHeader("Authorization");
        String academy = JWTUtil.getAcademy(token);
        DataVo dataVo = userBiz.selectAll(academy,queryInfo);
        if(dataVo.getData()==null){
            return new Result(Meta.FAIL);
        }
        Result result = new Result(Meta.SUCCESS);
        result.setData(dataVo);
        return result;
    }

    /**
     * 查询学院
     * @return
     */
    @GetMapping("/getAcademy")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3","4"})
    public Result selectAcademy(){
        List<AcademysPo> list = acadenyBiz.selectAcademy();
        Result result = new Result(Meta.SUCCESS,list);
        return result;
    }
    /**
     * 查询学院专业
     * @return
     */
    @GetMapping("/getMajor/{academy}")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3","4"})
    public Result selectMajor(@PathVariable String academy){
        List<MajorsPo> list = acadenyBiz.selectMajor(academy);
        Result result = new Result(Meta.SUCCESS,list);
        return result;
    }

    @PostMapping("/insertOne")
    @ApiOperation("院长主任添加用户")
    @RequiresRoles(logical = Logical.OR,value = {"2","3"})
    public Result addUser(@RequestBody UserVo userVo){
        String roleId = RoleUtil.roleChange(userVo.getRole());
        userVo.setRoleId(roleId);
        int flag = userBiz.addUser(userVo);
        Result result;
        if (flag>0){
            result = new Result(Meta.CREATED);
        }else{
            result = new Result(Meta.FAIL);
        }
        return result;
    }

    @PostMapping("/insertMore")
    @ApiOperation("管理员添加用户，赋予多角色")
    @RequiresRoles(value = "1")
    public Result adminAddUser(@RequestBody UserVo userVo){
        String roleId = userVo.getRoleId();
        if(roleId.contains(",")){
            String[] split = roleId.split("\\,");
            List<String> list = Arrays.asList(split);
            Collections.sort(list);
            roleId = String.join(",", list);
            userVo.setRoleId(roleId);
        }
        int flag = userBiz.addUser(userVo);
        Result result;
        if (flag>0){
            result = new Result(Meta.CREATED);
        }else{
            result = new Result(Meta.FAIL);
        }
        return result;
    }

    //删

    @DeleteMapping("/delete/{id}")
    @ApiOperation("删除用户")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3"})
    public Result deleteUser(@PathVariable String id){
        int flag = userBiz.deleteUser(id);
        Result result;
        if (flag>0){
            result = new Result(Meta.SUCCESS);
        }else{
            result = new Result(Meta.FAIL);
        }
        return result;

    }
    @PostMapping("/update")
    @ApiOperation("更新用户")
    @RequiresRoles(logical = Logical.OR,value = {"1","2","3"})
    //改
    public Result updateUser(@RequestBody UserVo userVo){
        UserPo userPo = new UserPo(userVo);
        String roleId = userPo.getRoleId();
        //添加用户信息应该需要将用户拥有的所有角色一起发过来
        if (userPo.getRoleId().equals("1")){
            userPo.setAcademy("");
        }
        if(roleId.contains(",")){
            String[] split = roleId.split("\\,");
            List<String> list = Arrays.asList(split);
            Collections.sort(list);
            roleId = String.join(",", list);
            userPo.setRoleId(roleId);
        }
        int flag = userBiz.updateUser(userPo);
        Result result;
        if (flag>0){
            result = new Result(Meta.SUCCESS);
        }else{
            result = new Result(Meta.FAIL);
        }
        return result;
    }

    //用户批量导入功能
    @PostMapping("/userUpload")
    @ApiOperation("更新用户")
    @RequiresRoles(logical = Logical.OR,value = {"1"})
    public Result userUpload(@RequestParam(value = "file", required = false) MultipartFile file,
                            HttpServletRequest request){

        //判断文件是否为空
        if (file.isEmpty()) {
            return new Result(Meta.FAIL);
        }
        try {
            InputStream is = file.getInputStream();

            //读取现有的工作簿
            HSSFWorkbook wb = new HSSFWorkbook(is);

            //遍历所有表，只支持xlsx，xls的是H的类
            HSSFSheet hssfSheet = wb.getSheetAt(0);
            int lastRowNum = hssfSheet.getLastRowNum();
            List<UsersForm> usersf = new ArrayList<>();
            for (int i = 0; i <= lastRowNum; i++) {
//            通过下标获取行
                HSSFRow row = hssfSheet.getRow(i);


                if (row == null) {
                    break;
                }
                //第一列为空就跳出
                if (row.getCell(0) == null) {
                    continue;
                }
//            从行中获取数据
                if (row.getRowNum() == 0) {
                    continue;
                }

                /**
                 * getNumericCellValue() 获取数字
                 * getStringCellValue 获取String，设置表格类型为String，可以避免很多问题
                 */
                //将数值类型设置为string类型

                row.getCell(0).setCellType(CellType.STRING);
                row.getCell(2).setCellType(CellType.STRING);
                if(row.getCell(10)!=null) row.getCell(10).setCellType(CellType.STRING);
                if(row.getCell(8)!=null) row.getCell(8).setCellType(CellType.STRING);
                if(row.getCell(9)!=null) row.getCell(9).setCellType(CellType.STRING);


                //把数据填入对应的类中
                UsersForm usersForm = new UsersForm();
                usersForm.setUser_id(row.getCell(0).getStringCellValue());
                usersForm.setUser_name(row.getCell(1).getStringCellValue());
                usersForm.setUser_password(row.getCell(2).getStringCellValue());
                usersForm.setUser_sex(row.getCell(3).getStringCellValue());
                if(row.getCell(4)!=null) usersForm.setUser_academy(row.getCell(4).getStringCellValue());
                if(row.getCell(5)!=null) usersForm.setStu_major(row.getCell(5).getStringCellValue());
                usersForm.setUser_roleid(RoleUtil.roleChange(row.getCell(6).getStringCellValue()) );
                if(row.getCell(7)!=null) usersForm.setRank(row.getCell(7).getStringCellValue());
                System.out.println(row.getCell(8));
                if(row.getCell(8)!=null) usersForm.setQq(row.getCell(8).getStringCellValue());

                if(row.getCell(9)!=null) usersForm.setEmail(row.getCell(9).getStringCellValue());
                if(row.getCell(10)!=null) usersForm.setPhone(row.getCell(10).getStringCellValue());


                //职称

                usersf.add(usersForm);

            }
            //批量存入数据库
            try{
                userBiz.insertUsers(usersf);
            }catch (DuplicateKeyException e){
                Throwable cause = e.getCause();
                String message = e.getMessage();
                String[] split = message.split("'");
                Result result = new Result(Meta.FAIL);
                result.setData("本次导入失败，请删除已存在用户 "+split[1]
                +"，后重新导入");
                return result;


            } finally {
                System.out.println("用户id重复");
                is.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            Result result = new Result(Meta.FAIL);
            result.setData("请检查上传文件中的必填属性，修改后重新上传");
            return result;
        }

        return new Result(Meta.SUCCESS);
    }


    //批量导入模板下载
    //文件下载
    @RequestMapping(value="/userDownload")
    @RequiresRoles(value = "1")
    public Result downloads(HttpServletResponse response ,
                            HttpServletRequest request) throws Exception{
        String filename = "userTem.xls";


        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据

        //跨域设置
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "*");


        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(filename, "UTF-8"));

        File file = new File(upload_path+"/user/"+filename);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();

        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();

        return new Result(Meta.SUCCESS);
    }

    //批量导入模板上传
    @RequestMapping("/userUpload/upload")
    @RequiresRoles(value = {"1"})
    public Result resultUpload(@RequestParam(value = "file", required = false) MultipartFile file,
                               HttpServletRequest request) throws IOException {

        String filename = "userTem.xls";
        //判断文件是否为空
        if (file.isEmpty()) {
            return new Result(Meta.FAIL);
        }



        File realPath = new File(upload_path+"/user");
        if (!realPath.exists()){
            realPath.mkdirs();
        }
        //每次上传删除上次上传文件
        File[] files = realPath.listFiles();
        for (File file1:files){
            file1.delete();
        }
        //上传文件地址
        System.out.println("上传文件保存地址："+realPath);

        //通过CommonsMultipartFile的方法直接写文件（注意这个时候）
        file.transferTo(new File(realPath +"/"+ filename));

        //保存到数据库

            return new Result(Meta.SUCCESS);
    }

}
